package Api.JunKa.RedeemJunKa;

import Util.HttpUtil;
import Util.Tools;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 骏卡支付提交接口
 * 功能：处理骏卡支付的参数构建、加密、签名和请求发送
 */
public class CardPaySubmitService {
    // 接口常量定义
    private static final String API_URL = "https://pay.Heepay.com/Api/CardPaySubmitService.aspx";
    private static final String CARD_TYPE = "10"; // 固定值
    private static final String TIMESTAMP_FORMAT = "yyyyMMddHHmmss";
    private static final String CHARSET_GBK = "GBK";

    // 配置参数
    private final String agentId;
    private final String refAgentId;
    private final String md5Key;
    private final String desKey;
    private final String notifyUrl;

    /**
     * 构造方法
     * @param agentId 商户编号
     * @param refAgentId 二级商户号
     * @param md5Key MD5密钥
     * @param desKey 3DES密钥
     * @param notifyUrl 通知回调地址
     */
    public CardPaySubmitService(String agentId, String refAgentId, String md5Key,
                                String desKey, String notifyUrl) {
        this.agentId = Objects.requireNonNull(agentId, "商户编号不能为空");
        this.refAgentId = refAgentId == null ? "" : refAgentId;
        this.md5Key = Objects.requireNonNull(md5Key, "MD5密钥不能为空");
        this.desKey = Objects.requireNonNull(desKey, "3DES密钥不能为空");
        this.notifyUrl = Objects.requireNonNull(notifyUrl, "通知地址不能为空");
    }

    /**
     * 提交骏卡支付请求
     * @param cardData 卡信息字符串（格式：卡号1,密码1,金额1丨卡号2,密码2,金额2...）
     * @param payAmount 支付金额
     * @param clientIp 客户端IP
     * @param goodsDetail 商品详情JSON字符串
     * @return 接口响应结果
     * @throws Exception 处理过程中的异常
     */
    public String submitPayment(String cardData, String payAmount, String clientIp, String goodsDetail)
            throws Exception {
        // 参数校验
        validateParameters(cardData, payAmount, clientIp);

        // 生成时间戳和订单相关信息
        String timestamp = generateTimestamp();
        String billId = timestamp; // 使用时间戳作为订单号，实际应使用业务订单号

        // 处理商品详情（URL编码）
        String encodedGoodsDetail = encodeGoodsDetail(goodsDetail);

        // 加密卡信息
        String encryptedCardData = encryptCardData(cardData);

        // 生成签名
        String sign = generateSign(agentId, billId, timestamp, encryptedCardData, payAmount);

        // 构建请求参数
        Map<String, String> parameters = buildParameters(agentId, billId, timestamp,
                encryptedCardData, payAmount, clientIp, encodedGoodsDetail, sign);

        // 发送请求
        return sendRequest(parameters);
    }

    /**
     * 参数校验
     */
    private void validateParameters(String cardData, String payAmount, String clientIp) {
        if (cardData == null || cardData.trim().isEmpty()) {
            throw new IllegalArgumentException("卡信息不能为空");
        }
        if (payAmount == null || !payAmount.matches("\\d+(\\.\\d{1,2})?")) {
            throw new IllegalArgumentException("支付金额格式错误，应为数字且最多两位小数");
        }
        if (clientIp == null || !clientIp.matches("\\d+\\.\\d+\\.\\d+\\.\\d+")) {
            throw new IllegalArgumentException("客户端IP格式错误");
        }
    }

    /**
     * 生成时间戳
     */
    private String generateTimestamp() {
        return new SimpleDateFormat(TIMESTAMP_FORMAT).format(new Date());
    }

    /**
     * 对商品详情进行URL编码
     */
    private String encodeGoodsDetail(String goodsDetail) throws UnsupportedEncodingException {
        if (goodsDetail == null || goodsDetail.trim().isEmpty()) {
            return "";
        }
        return URLEncoder.encode(goodsDetail, CHARSET_GBK);
    }

    /**
     * 加密卡信息
     */
    private String encryptCardData(String cardData) {
        byte[] gbkBytes = cardData.getBytes(Charset.forName(CHARSET_GBK));
        return Tools.encrypt3DES(gbkBytes, desKey);
    }

    /**
     * 生成签名
     */
    private String generateSign(String agentId, String billId, String timestamp,
                                String encryptedCardData, String payAmount) {
        StringBuilder signSource = new StringBuilder();
        signSource.append("agent_id=").append(agentId)
                .append("&bill_id=").append(billId)
                .append("&bill_time=").append(timestamp)
                .append("&card_type=").append(CARD_TYPE)
                .append("&card_data=").append(encryptedCardData)
                .append("&pay_amt=").append(payAmount)
                .append("&notify_url=").append(notifyUrl)
                .append("&time_stamp=").append(timestamp)
                .append("|||").append(md5Key);

        String signSourceStr = signSource.toString();
        System.out.println("待签名串：" + signSourceStr);
        return Tools.getMD5(signSourceStr);
    }

    /**
     * 构建请求参数
     */
    private Map<String, String> buildParameters(String agentId, String billId, String timestamp,
                                                String encryptedCardData, String payAmount,
                                                String clientIp, String encodedGoodsDetail, String sign) {
        Map<String, String> parameters = new HashMap<>();
        parameters.put("agent_id", agentId);
        parameters.put("pay_amt", payAmount);
        parameters.put("card_type", CARD_TYPE);
        parameters.put("card_data", encryptedCardData);
        parameters.put("bill_id", billId);
        parameters.put("bill_time", timestamp);
        parameters.put("notify_url", notifyUrl);
        parameters.put("time_stamp", timestamp);
        parameters.put("client_ip", clientIp);
        parameters.put("goods_detail", encodedGoodsDetail);
        parameters.put("sign", sign);

        // 添加二级商户号（如果有值）
        if (!refAgentId.isEmpty()) {
            parameters.put("ref_agent_id", refAgentId);
        }

        return parameters;
    }

    /**
     * 发送请求
     */
    private String sendRequest(Map<String, String> parameters) throws IOException {
        return HttpUtil.sendPost2(API_URL, parameters);
    }

    public static void main(String[] args) {
        try {
            // 初始化配置参数
            String agentId = "1664502";
            String refAgentId = "";
            String md5Key = "651886F030134F848F548A12";
            String desKey = "DA95D1144CE146CB89130E1A";
            String notifyUrl = "https://pay.Heepay.com";

            // 创建服务实例
            CardPaySubmitService service = new CardPaySubmitService(
                    agentId, refAgentId, md5Key, desKey, notifyUrl);

            // 准备请求参数
            String cardData = "2310192225830501,1111191111111,1丨2310192225830501,111114894898411111,2";
            String payAmount = "1";
            String clientIp = "127.127.127.127";
            String goodsDetail = "{\"id\":\"商品编号\",\"name\":\"商品名称\",\"num\":\"商品数量\",\"price\":\"商品单价\",\"url\":\"https://pay.Heepay.com\"}";

            // 提交支付请求
            String response = service.submitPayment(cardData, payAmount, clientIp, goodsDetail);
            System.out.println("接口响应：" + response);

        } catch (IllegalArgumentException e) {
            System.err.println("参数错误：" + e.getMessage());
        } catch (Exception e) {
            System.err.println("支付提交失败：" + e.getMessage());
            e.printStackTrace();
        }
    }
}
